//! # 基础认证类型定义
//!
//! 提供基础的认证类型，避免循环依赖

use std::collections::HashMap;
use std::time::SystemTime;
use serde::{Deserialize, Serialize};

/// 认证结果类型
pub type AuthResult<T> = Result<T, AuthError>;

/// 认证错误
#[derive(Debug, thiserror::Error)]
pub enum AuthError {
    #[error("Authentication failed: {0}")]
    AuthenticationFailed(String),
    #[error("Authorization failed: {0}")]
    AuthorizationFailed(String),
    #[error("Invalid token: {0}")]
    InvalidToken(String),
    #[error("Token expired")]
    TokenExpired,
    #[error("Internal error: {0}")]
    InternalError(String),
}

/// 主体类型
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum PrincipalType {
    /// 用户
    User,
    /// 管理员
    Admin,
    /// 服务
    Service,
    /// 系统
    System,
    /// 匿名
    Anonymous,
    /// 自定义类型
    Custom(String),
}

/// 主体（认证后的用户/服务）
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Principal {
    /// 主体ID
    pub id: String,
    /// 主体名称
    pub name: String,
    /// 主体类型
    pub principal_type: PrincipalType,
    /// 角色列表
    pub roles: Vec<String>,
    /// 权限列表
    pub permissions: Vec<String>,
    /// 附加属性
    pub attributes: HashMap<String, String>,
    /// 过期时间
    pub expires_at: Option<SystemTime>,
}

impl Principal {
    /// 创建新的主体
    pub fn new(id: String, name: String, principal_type: PrincipalType) -> Self {
        Self {
            id,
            name,
            principal_type,
            roles: Vec::new(),
            permissions: Vec::new(),
            attributes: HashMap::new(),
            expires_at: None,
        }
    }

    /// 添加角色
    pub fn add_role(mut self, role: String) -> Self {
        self.roles.push(role);
        self
    }

    /// 添加权限
    pub fn add_permission(mut self, permission: String) -> Self {
        self.permissions.push(permission);
        self
    }

    /// 添加属性
    pub fn add_attribute(mut self, key: String, value: String) -> Self {
        self.attributes.insert(key, value);
        self
    }

    /// 设置过期时间
    pub fn with_expiry(mut self, expires_at: SystemTime) -> Self {
        self.expires_at = Some(expires_at);
        self
    }

    /// 检查是否有指定角色
    pub fn has_role(&self, role: &str) -> bool {
        self.roles.contains(&role.to_string())
    }

    /// 检查是否有指定权限
    pub fn has_permission(&self, permission: &str) -> bool {
        self.permissions.contains(&permission.to_string())
    }

    /// 检查是否为管理员
    pub fn is_admin(&self) -> bool {
        matches!(self.principal_type, PrincipalType::Admin)
    }

    /// 获取角色列表
    pub fn get_roles(&self) -> &Vec<String> {
        &self.roles
    }

    /// 获取权限列表
    pub fn get_permissions(&self) -> &Vec<String> {
        &self.permissions
    }
}

/// 资源
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Resource {
    /// 服务名称
    pub service: String,
    /// 请求路径
    pub path: String,
    /// HTTP 方法
    pub method: String,
}

impl Resource {
    /// 创建新的资源
    pub fn new(service: String, path: String, method: String) -> Self {
        Self { service, path, method }
    }

    /// 获取资源标识符
    pub fn get_resource_id(&self) -> String {
        format!("{}:{}:{}", self.service, self.method.to_lowercase(), self.path)
    }
}

/// 权限检查器 trait
#[async_trait::async_trait]
pub trait PermissionChecker: Send + Sync {
    /// 检查权限
    async fn check(&self, principal: &Principal, permission: &str) -> AuthResult<bool>;

    /// 检查资源访问权限
    async fn check_resource(&self, principal: &Principal, resource: &Resource) -> AuthResult<bool> {
        let permission = resource.get_resource_id();
        self.check(principal, &permission).await
    }
}